<template>
  <base-modal :title="title" :width="showAcceptForm ? '800px' : '640px'" :show.sync="visible" class="task-plantime-dialog" :append-to-body="appendToBody">
    <div v-loading="loading">
      <div v-if="showPlanTime && canEditPlanTime" :class="['base-modal-content', { 'task-flow-accept': showAcceptForm}]">
        <div :class="{ 'task-flow-node-accept': showAcceptForm}">
          <div :class="['base-modal-content-selecttime', { 'task-flow-node-accept-time': showAcceptForm}]">
            <form-item :label="$t('common.form.type.planStartTime')" v-if="startField.id || isShowStartTime">
              <form-plantime :picker-options="planTimeDatePickeroptions" :field="startField.id ? startField : planStartField" :value="planStartTime" @update="update" :clearable="false"></form-plantime>
              <div class="error-tip" v-if="planStartTimeError">{{planStartTimeError}}</div>
            </form-item>
          </div>

          <div :class="{ 'task-flow-node-accept-time': showAcceptForm}">
            <form-item :label="$t('common.form.type.planEndTime')" v-if="endField.id || isShowEndTime">
              <form-planendtime :picker-options="planTimeDatePickeroptions" :start-time="planStartTime" :field="endField.id ? endField : planEndField" :value="planEndTime" @update="update" :clearable="false"></form-planendtime>
              <div class="error-tip" v-if="planEndTimeError">{{planEndTimeError}}</div>
            </form-item>
          </div>
        </div>

        <div>
          <el-checkbox class="task-planTime-notice" v-model="sendSMS" v-if="(action == 'modifyPlanTime'||action == 'modifyPlanStartTime'||action == 'modifyPlanEndTime') && enableSendSms">{{$t('task.sendSmsNotice')}}</el-checkbox>
        </div>
      </div>
      <div :class="{ 'task-flow-node-accept-calendar': showAcceptForm}" v-if="showPlanTime && canEditPlanTime && this.planStartTime && this.planEndTime && isEmptyGanttData && isAcceptCalendarTime">
        <template v-if="showCalendar">
          <div class="top-tips">
            <!--<p v-if="isConflict" class="warning-tip">
              <i class="iconfont icon-info"></i>
              与您的日程存在冲突
            </p>
            <p v-else class="perfe-tip">
              <i class="iconfont icon-check-fill"></i>
              当前暂无日程冲突
            </p>-->
            <div class="type-desc">
              <div class="plane-type"></div>
              <div class="plane-content time-text">{{$t('common.form.type.planTime')}}</div>
              <div class="busy-type"></div>
              <div class="plane-content time-text">{{$t('task.detail.components.busyTime')}}</div>
              <div class="config-type"></div>
              <div class="time-text">{{$t('task.detail.components.conflictTime')}}</div>
            </div>
          </div>
          <div>
            <gantt-chart
                :gantt-data="GanttData"
                :time-section="GanttTime"
                :acceptEnable="true"
            />
          </div>
        </template>
        <div v-else class="task_gantt__area--error">
          <img :src="noDataImage">
          <span>{{$t('task.tip.planTimeTip1')}}</span>
        </div>
      </div>
      <!--      -->
      <div class="task-initiate-calendar-dialog-form">
        <form-builder
            class="bbx-cell-form-builder"
            ref="taskCustomeCalendarRef"
            mode="taskCustomeCalendar"
            formStatus="edit"
            formEditingMode="edit"
            :fields="acceptFields"
            :value="formValue"
            :form-cell-count="2"
            @getDeleteFiles="getDeleteFiles"
            @update="updateForm"
        >
        </form-builder>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <template>
        <el-button :disabled="pending || pendingStorage" @click="visible = false">{{$t('common.base.cancel')}}</el-button>
        <el-button v-if="showAcceptForm" :disabled="pending" :loading="pendingStorage" @click="toTemporaryStorage">{{ $t('common.base.temporaryStorage') }}</el-button>
        <el-button :disabled="pending || pendingStorage" v-if="isAcceptCalendarTime && isRefuse" type="danger" @click="refuse">{{$t('common.base.refuse')}}</el-button>
        <el-button :loading="pending" :disabled="pendingStorage" type="primary" @click="submit()">{{ isAcceptCalendarTime ? $t('common.base.accept') : $t('common.base.makeSure') }}</el-button>
      </template>
    </div>
  </base-modal>
</template>

<script>
/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import GanttChart from '@src/modules/calendar/components/vue-gantt-chart/gantt-chart.vue'
import * as CalendarApi from '@src/api/CalendarApi.ts';
import moment from 'moment'
import { isEmpty } from '@src/util/type'
/* util */
import _ from 'lodash'
import { safeNewDate } from '@src/util/time';
import { isDevelopment } from '@src/util/platform';
import { RESOURCE_PREFIX } from '@src/util/linkSwitch';
import { parseDateTime, getTimestamp, useFormTimezone } from 'pub-bbx-utils';
import i18n from '@src/locales'
import { GrayFunctionEnum } from 'pub-bbx-global/pageType/dist/grayFunction'
import { getRootWindow } from "@src/util/dom";
const PLAN_TASK_TIME_VALIATE = i18n.t('task.tip.planTimeTip2')
const planStartField = { 
  displayName: i18n.t('common.form.type.planStartTime'),
  formType:'planStartTime',
  setting: {dateType: 'dateTime'}
};
const planEndField = { 
  displayName: i18n.t('common.form.type.planEndTime'),
  formType:'planEndTime',
  setting: {dateType: 'dateTime'}
};
const resourcePrefix = isDevelopment() ? '' : RESOURCE_PREFIX
import { getOssUrl } from '@src/util/assets'
import { draftSaveCustomerNode, getCurrentDraftCustomerNode, getTaskCustomNodeFields} from "@src/api/TaskApi.ts";
import * as FormUtil from "@form/util";
const noDataImage = getOssUrl('/no_data.png')
const { disposeFormSubmitTime } = useFormTimezone()
export default {
  name: 'calendar-plantime-dialog',
  components: {
    GanttChart
  },
  props: {
    task: {
      type: Object,
      default: () => ({})
    },
    startField: {
      type: Object,
      default: () => ({})
    },
    endField: {
      type: Object,
      default: () => ({})
    },
    // 工单设置修改计划时间开关
    modifiable: {
      type: Boolean,
      default: true
    },
    successCallback: {
      type: Function,
      default() {
        window.location.href = `${resourcePrefix}/task/view/${this.task.id}`
      }
    },
    stateButtonData: {
      type: Array,
      default: () => [],
    },
    isAcceptCalendarTime: {
      type: Boolean,
      default: true,
    },
    enableSendSms: {
      type: Boolean,
      default: true,
    },
    isRefuse: {
      type: Boolean,
      default: true,
    },
    appendToBody:{
      type: Boolean,
      default: false,
    }
  },
  data: () => {
    return {
      noDataImage,
      loading: false,
      visible: false,
      pending: false,
      action: '',
      planStartTime: '',
      planEndTime:'',
      planTimeDatePickeroptions: {
        disabledDate(time) {
          return time.getTime() < safeNewDate(safeNewDate().toLocaleDateString()).getTime()
        }
      },
      GanttData: null,
      isConflict: false,
      sendSMS: false,
      acceptFields: [], // 接单节点配置的自定义字段
      formValue: {},
      needServerDelFiles: [],
      title: '',
      canEditPlanTime: true,
      pendingStorage: false,
      temporaryStorageVal: {}, // 暂存的数据
    }
  },
  computed: {
    // 工单节点拓展灰度
    taskFlowExtend() {
      const RootWindow = getRootWindow(window);
      return RootWindow?.grayAuth?.[GrayFunctionEnum.TaskFlowExtend] ?? false // 工单流程节点灰度
    },
    // 接单节点是否有字段
    showAcceptForm() {
      return this.acceptFields?.length ?? false
    },
    validatePlantTimeError(){
      const { planStartTime, planEndTime } = this
      return planStartTime && planEndTime && getTimestamp(this.planEndTime) < getTimestamp(this.planStartTime) ? PLAN_TASK_TIME_VALIATE : ''
    },
    planStartTimeError(){
      return (this.startField?.id || this.task?.planStartTimeShow) && this.validatePlantTimeError
    },
    planEndTimeError(){
      return (this.endField?.id || this.task?.planEndTimeShow) && this.validatePlantTimeError
    },
    isEmptyGanttData() {
      return !isEmpty(this.GanttData)
    },
    dateType1() {
      return this.startField?.setting?.dateType
    },
    dateType2() {
      return this.endField?.setting?.dateType
    },
    GanttTime() {
      return [moment(this.planStartTime).format('YYYY/MM/DD HH:mm'), moment(this.planEndTime).format('YYYY/MM/DD HH:mm')]
    },
    isShowStartTime() {
      return this.task?.planStartTimeShow;
    },
    isShowEndTime() {
      return this.task?.planEndTimeShow;
    },
    planStartField() {
      return planStartField;
    },
    planEndField() {
      return planEndField;
    },
    showCalendar() {
      if(this.planEndTime && this.planStartTime){
        let time = safeNewDate(this.planEndTime).getTime() - safeNewDate(this.planStartTime).getTime()
        let flagTimeValid = time <= (1000 * 60 * 60 * 24 * 30);
        return flagTimeValid;
      }
      return true;
    },
    // 判断是否显示计划开始时间和计划完成时间
    showPlanTime() {
      return (this.startField?.id || this.isShowStartTime) || (this.endField?.id || this.isShowEndTime)
    },
  },
  methods: {
    // 删除的附件
    getDeleteFiles(files) {
      this.needServerDelFiles = [...this.needServerDelFiles, ...files]
    },
    // 更新表单字段
    updateForm({ field, newValue }) {
      if(!field) return
      const { fieldName = '' } = field || {};

      this.$set(this.formValue, fieldName, newValue);
    },
    async calendarClashInfo(){
      try {
        const params = {
          planStartTime: safeNewDate(this.planStartTime),
          planEndTime: safeNewDate(this.planEndTime),
          taskId: this.task.id
        };
        const res = await CalendarApi.calendarClashInfo(params);
        this.GanttData = [res?.result]
      } catch (error) {
        console.error('calendarClashInfo error', error);
      }
    },
    async checkCalendarClash(){
      try {
        const params = {
          planStartTime: safeNewDate(this.planStartTime),
          planEndTime: safeNewDate(this.planEndTime),
          taskId: this.task.id
        };
        const res = await CalendarApi.checkCalendarClash(params);
        this.isConflict = res && res.result
      } catch (error) {
        console.error('checkCalendarClash error', error);
      }
    },
    /**
    * @description 更新计划时间
    */
    update({ field, newValue, oldValue }) {
      let formType = field.formType || field.fieldName || field?.field;
      this.$set(this, formType, newValue);
      if(this.planStartTime && this.planEndTime){
        this.calendarClashInfo()
        // this.checkCalendarClash()
      }
    },
    // 接单前判断是否1。有无计划开始和计划完成时间，接单节点是否配置了自定义字段
    async beforeOpenForAccept(action) {
      try {
        let acceptFields = []
        // 判断接单接单有没有开启节点灰度，开启了需要查询配置表单
        if(this.taskFlowExtend) {
          const res = await getTaskCustomNodeFields({ taskId: this.task.id });
          acceptFields  = res?.result ?? []
          // 获取暂存的字段值
          const { success = false, result = {} } = await getCurrentDraftCustomerNode({ taskId: this.task.id, currentNodeId: 'accept' })
          if(success) this.temporaryStorageVal = result?.formData ?? {}
        }
        if((this.startField?.id) || (this.endField?.id) || acceptFields?.length) {
          this.acceptFields = acceptFields;
          await this.openDialog(action)
        }else {
          this.submit(action)
        }

      } catch (e) {
        console.error(e)
      }
    },
    /**
    * @description 打开计划时间弹窗
    */
    async openDialog(action = 'modifyPlanTime') {
      try {
        this.loading = true
        setTimeout(() => {
          this.loading = false;
        }, 1000);
        this.action = action;
        // 获取引用字段值
        const val = _.cloneDeep(this.task.attribute)
        let formDate = {};
        this.acceptFields?.forEach(item => {
          // 如果暂存存过，用暂存的值，否则用工单详情的值
          if(item.fieldName in this.temporaryStorageVal) {
            this.$set(formDate, item.fieldName, this.temporaryStorageVal[item.fieldName])
          }else {
            val?.[item.fieldName] && this.$set(formDate, item.fieldName, val[item.fieldName])
          }
        })
        this.formValue = FormUtil.initialize(this.formField, formDate);
        // 如果暂存存过，用暂存的值，否则用工单详情的值
        let planStartTime = ('planStartTime' in this.temporaryStorageVal) ? (this.temporaryStorageVal?.planStartTime || '') : (this.task.planStartTime || '');
        let planEndTime =  ('planEndTime' in this.temporaryStorageVal) ? (this.temporaryStorageVal?.planEndTime || '') : (this.task.planEndTime || '');

        // 计划时间格式为日期时需格式化
        if (this.dateType1 == 'date' && planStartTime) {
          planStartTime = planStartTime.slice(0, 10);
        }
        this.planStartTime = planStartTime;
        if (this.dateType2 == 'date' && planEndTime) {
          planEndTime = planEndTime.slice(0, 10);
        }
        this.planEndTime = planEndTime;

        if(this.planStartTime && this.planEndTime){
          this.calendarClashInfo()
          // this.checkCalendarClash()
        }

        // 工单设置禁用了修改计划时间并且有计划时间
        if (!this.modifiable) {
          let num = 0;
          if(this.startField.id){
            if(planStartTime){
              num++;
            }
          }else{
            num++;
          }
          if(this.endField.id){
            if(planEndTime){
              num++;
            }
          }else{
            num++;
          }
          if(num > 1){
            // 上边已经对格式为日期时格式化了，现禁止修改计划时间，所以初始化为原始值
            if (this.dateType1 == 'date') this.planStartTime = this.task.planStartTime;
            if (this.dateType2 == 'date') this.planEndTime = this.task.planEndTime;
            // 接单接单有配置表单，不能直接提交，
            if(this.showAcceptForm) {
              this.canEditPlanTime = false;
            }else {
              this.submit();
              return;
            }
          }
        }

        // title
        if(this.showPlanTime && this.canEditPlanTime) {
          this.title = this.$t('task.modifyPlanTime')
        }else {
          this.title = this.$t('common.task.acceptTitle')
        }
        this.sendSMS = false;
        this.visible = true;
      } catch (e) {
        console.error()
      }
    },
    refuse() {
      this.$emit('refuse')
    },
    async submit(action = '') {

      const valid = await this.$refs.taskCustomeCalendarRef?.validate(false) ?? true

      if(action){
        this.action = action;
      }
      const { 
        startField,
        endField,
        planStartTime,
        planEndTime,
        planStartTimeError,
        planEndTimeError,
        isAcceptCalendarTime,
        sendSMS,
        task,
        $platform,
        pending,
        $t,
      } = this
      if(startField.isNull == 0 && !planStartTime) return $platform.alert($t('task.tip.pleaseFillInSth', {content: startField.displayName}));
      if(endField.isNull == 0 && !planEndTime) return $platform.alert($t('task.tip.pleaseFillInSth', {content: endField.displayName}));

      if(planStartTimeError || planEndTimeError) return

      if(!valid) return ;

      let params = { 
        taskId: task.id, 
        planStartTime: getTimestamp(planStartTime), 
        planEndTime: getTimestamp(planEndTime), 
      };

      if(!isAcceptCalendarTime){
        params.sendSMS = sendSMS;
      }
      if(this.showAcceptForm) {
        params.formData = disposeFormSubmitTime(this.acceptFields, this.formValue) // 处理国际化时间转换
        params.needServerDelFiles = this.needServerDelFiles;
      }

      if (pending) return;
      this.pending = true;

      TaskApi[this.action](params)
        .then(res => {
          if (res.success) {
            if(['acceptFromPool', 'accept'].includes(this.action)) {
              this.$track.clickStat(this.$track.formatParams('ACCEPT_TASK_SUCCESS'));
            }
            this.visible = false
            
            if(this.isShowStartTime && this.isShowEndTime){
              this.successCallback({
                start: planStartTime,
                end: planEndTime,
              })
            }else if(this.isShowStartTime){
              this.successCallback({start: planStartTime})
            }else if(this.isShowEndTime){
              this.successCallback({end: planEndTime})
            }else {
              this.successCallback()
            }
          } else {
            this.$platform.alert(res.message);
          }
        })
        .finally(() => {
          this.pending = false
        })
    },

    /*暂存表单*/
    async toTemporaryStorage() {
      try {
        this.pendingStorage = true;

        let formData = disposeFormSubmitTime(this.acceptFields, this.formValue) // 处理国际化时间转换

        formData = {
          ...formData,
          planStartTime: getTimestamp(this.planStartTime),
          planEndTime: getTimestamp(this.planEndTime),
        }

        const params = {
          taskId: this.task.id,
          currentNodeId: 'accept',
          formData,
        }
        const { success, message } = await draftSaveCustomerNode(params)

        if(!success) return this.$message.error(message);

        this.$message.success(this.$t('common.base.temporarySaveSuccess'));

        this.visible = false;
      } catch (e) {
        console.error(e)
      } finally {
        this.pendingStorage = false;
      }
    },
  }
}
</script>

<style lang="scss">
.task-plantime-dialog {
  .base-modal-content {
    padding: 8px 16px;
    .form-item > label {
      width: 120px!important
    }
    .form-datetime {
      width: 50%;
    }
    .error-tip {
      color: #f56c6c;
      font-size: 12px;
    }
  }
  .top-tips {
    margin-left: 16px;
    .warning-tip {
      color: #f56c6c;
    }
    .icon {
      font-size: 16px;
      vertical-align: bottom;
    }
    .icon-check-fill {
      color: $color-primary-light-6;
    }
    .type-desc {
      display: flex;
      align-items: center;
      .plane-type {
        width: 12px;
        height: 12px;
        background: #67C23A;
        margin-right: 4px;
        opacity: 0.6;
      }
      .plane-content {
        margin-right: 16px;
      }
      .time-text {
        height: 17px;
        font-size: 12px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #8C8C8C;
        line-height: 17px;
      }
      .busy-type {
        width: 12px;
        height: 12px;
        background: #FAAB0C;
        opacity: 0.35;
        margin-right: 4px;
      }
      .config-type {
        width: 12px;
        height: 12px;
        background: #82B830;
        margin-right: 4px;
      }
    }
  }
  
  .form-item {
    margin-bottom: 6px;
    
    & > label {
      padding-left: 0;
      margin-right: 0 !important;
    }
  }
  
  .task-planTime-notice {
    margin-bottom: 0;
  }
  .task_gantt__area--error {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 10px 10px;
    font-size: 1em;
    color: $text-color-regular;
    img {
      width: 160px;
      height: 160px;
      margin-bottom: 8px;
    }
  }
}
.task-initiate-calendar-dialog-form {
  .form-builder {
    padding: 12px 4px !important;
    width: 100% !important;
  }
}
</style>

<style lang="scss" scoped>
.task-flow-accept {
  padding-right: 20px;
}
.task-flow-node-accept {
  display: flex;
  width: 100%;
  justify-content: space-between;

  &-time {
    width: 380px;
    &:first-child {
      margin-right: 24px;
    }
    .form-datetime {
      width: 100% !important;
    }
  }
}
.task-flow-node-accept-calendar {
  margin-right: 20px;
}
</style>